
package com.code.ape.codeape.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.code.ape.codeape.admin.api.dto.SysWarnDTO;
import com.code.ape.codeape.admin.api.entity.constant.SysPostConstant;
import com.code.ape.codeape.admin.api.dto.SysHospitalDTO;
import com.code.ape.codeape.admin.api.entity.*;
import com.code.ape.codeape.admin.api.util.ParamResolver;
import com.code.ape.codeape.admin.mapper.*;
import com.code.ape.codeape.admin.service.SysHospitalService;
import com.code.ape.codeape.admin.service.SysPostService;
import com.code.ape.codeape.admin.service.SysWarnService;
import com.code.ape.codeape.common.core.constant.SecurityConstants;
import com.code.ape.codeape.common.core.exception.ErrorCodes;
import com.code.ape.codeape.common.core.util.AssertUtil;
import com.code.ape.codeape.common.core.util.MsgUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 医院表
 *
 * @author 公众号：码猿技术专栏   版权：不才陈某所署，侵权必究
 * @date 2023-05-17 17:19:22
 */
@Service
@RequiredArgsConstructor
public class SysHospitalServiceImpl extends ServiceImpl<SysHospitalMapper, SysHospital> implements SysHospitalService {

	private final SysUserMapper sysUserMapper;

	private final SysRoleMapper sysRoleMapper;

	private final SysUserRoleMapper sysUserRoleMapper;

	private final SysPostService sysPostService;

	private final SysWarnService sysWarnService;

	private final static PasswordEncoder ENCODER=new BCryptPasswordEncoder();


	@Override
	public List<SysHospital> listByUserName(String username) {
		//注意：系统管理员拥有全部的医院权限
		List<SysUser> sysUsers = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
		if (CollectionUtil.isEmpty(sysUsers))
			return null;
		List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(Wrappers.<SysUserRole>lambdaQuery().in(SysUserRole::getUserId, sysUsers.stream().map(SysUser::getUserId).collect(Collectors.toList())));
		List<String> roleCodes = sysRoleMapper.selectList(Wrappers.<SysRole>lambdaQuery().in(SysRole::getRoleId, sysUserRoles.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()))).stream().map(data-> SecurityConstants.ROLE+data.getRoleCode()).collect(Collectors.toList());
		return baseMapper.selectList(Wrappers.<SysHospital>lambdaQuery().in(!roleCodes.contains(SecurityConstants.SYSTEM_ADMIN_CODE),SysHospital::getId,sysUsers.stream().map(SysUser::getHosId).collect(Collectors.toList())));
	}

	@Transactional
    @Override
    public Boolean saveHos(SysHospitalDTO dto) {
		//step1 由于账号+hosId是唯一关联的，因此这里不用校验账号的唯一性，直接插入即可
		SysHospital sysHospital = new SysHospital();
		BeanUtil.copyProperties(dto,sysHospital);
		int i = baseMapper.insert(sysHospital);
		Assert.isTrue(i==1, MsgUtils.getMessage(ErrorCodes.SYS_HOS_ADD_SYSTEM));
		//step2 新增用户，直接赋予管理员的角色
		SysUser sysUser = new SysUser();
		sysUser.setHosId(sysHospital.getId());
		sysUser.setUsername(dto.getUsername());
		sysUser.setName(dto.getName());
		//赋予默认密码
		sysUser.setPassword(ENCODER.encode(ParamResolver.getStr("HOS_ADMIN_PASSWORD")));
		sysUser.setLockFlag("0");
		int j = sysUserMapper.insert(sysUser);
		Assert.isTrue(j==1, MsgUtils.getMessage(ErrorCodes.SYS_HOS_ADD_SYSTEM));
		//step3 添加角色
		SysUserRole sysUserRole=new SysUserRole();
		sysUserRole.setUserId(sysUser.getUserId());
		sysUserRole.setRoleId(sysRoleMapper.selectOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode,ParamResolver.getStr("ADMIN_CODE","ADMIN"))).getRoleId());
		int k=sysUserRoleMapper.insert(sysUserRole);
		Assert.isTrue(k==1, MsgUtils.getMessage(ErrorCodes.SYS_HOS_ADD_SYSTEM));

		//step4 添加系统内置的岗位
		List<SysPost> sysPostList = SysPostConstant.buildSysPost(sysHospital.getId());
		boolean b = sysPostService.saveBatch(sysPostList);
		AssertUtil.isTrue(b,MsgUtils.getMessage(ErrorCodes.SYS_HOS_ADD_SYSTEM));
		//todo step5 添加医院内置的配置，待完善

		//todo step6 添加系统内置的预警配置
		List<SysWarn> sysWarns = SysWarnDTO.buildInnerSysWarn(sysHospital.getId());
		boolean rows = sysWarnService.saveBatch(sysWarns);
		AssertUtil.isTrue(rows,MsgUtils.getMessage(ErrorCodes.SYS_HOS_ADD_SYSTEM));
		return Boolean.TRUE;
    }
}
